import java.util.Calendar;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class EpochData {

    private String[] satellites;
    static int i;
    private static StringUtils util;
    private static int epochNumSats;
    private static long timeInMilliSecs;
    private static long time;
    private static double[] obs = new double[5];
    private static int[] ll = new int[5]; //loss of lock flag
    private static int[] ss = new int[5]; //signal strength flag

    // Used to match PRN numbers with out the constell flag
    private static Pattern p = Pattern.compile("\\d+");

    EpochData () {
        i = 0;
    }

    public void addSatellite(String satID) {
        satellites[i] = satID;
        i++;
    }

    public void printSatellites() {
        for (int j = 0; j < satellites.length; j++) {
            System.out.println("Printing Satellite :"+satellites[j]);
        } 
    }

    public String getSatellite(int j) {
        return satellites[j];
    }

    // Return only the PRN part of the code   
    public int getPRN(int j) {
        String sat = getSatellite(j);
        Matcher m = p.matcher(sat);
        while(m.find()) {
            String PRN = m.group();
            Integer satPRN = Integer.parseInt( PRN );
            return satPRN;
        } 
        return 0;
    }

    // Retunr the constellchar code
    public String getConstell(int j) {
        String sat = getSatellite(j);
        String constell = sat.substring(0,1);
        return constell;
    }
 
    public double getObs(int j) {
        return obs[j];
    } 
    
    public int getLL(int j) {
        return ll[j];
    } 
    
    public int getSS(int j) {
        return ss[j];
    } 
    //
    // Get the Epoch time for this set of observations
    //  ie 06 1 1 0 0 5.000000 0 10G22G14G19R 6G 1R 5 3R22G11G15
    //
    public String parseObsTime(String line) {
        //System.out.println("LINE "+line);
        Integer yy = Integer.parseInt( util.lrtrim(line.substring(0,3)) );
        //System.out.println("yy  :"+yy);
        Integer mm = Integer.parseInt( util.lrtrim(line.substring(4,6)) );
        //System.out.println("mm  :"+mm);
        Integer dd = Integer.parseInt( util.lrtrim(line.substring(7,9)) );
        //System.out.println("dd  :"+dd);
        Integer hh = Integer.parseInt( util.lrtrim(line.substring(11,12)) );
        //System.out.println("hh  :"+hh);
        Integer min= Integer.parseInt( util.lrtrim(line.substring(14,15)) );
        //System.out.println("min :"+min);
        Integer ss = Integer.parseInt( util.lrtrim(line.substring(17,18)) );
        //System.out.println("ss  :"+ss);
        String msec= line.substring(19,26);
        //System.out.println("msec:"+msec);

        Calendar cal = Calendar.getInstance();
        if(yy < 80) {
            yy = yy + 2000;
        }
        else {
            yy = yy + 1900;
        }
        if( mm == 0 ) {
            mm = 12;
        }
        else {
            mm--;
        }
        //System.out.println(yy);
        cal.set(Calendar.YEAR,yy);
        cal.set(Calendar.MONTH,mm);
        cal.set(Calendar.DAY_OF_MONTH,dd);
        cal.set(Calendar.HOUR_OF_DAY,hh);
        cal.set(Calendar.MINUTE,min);
        cal.set(Calendar.SECOND,ss);
        cal.set(Calendar.MILLISECOND,0);
        //long diff = cal.getTimeInMillis();
        timeInMilliSecs = cal.getTimeInMillis();
        time = timeInMilliSecs/1000 ;
        //System.out.println("Time:"+timeInMilliSecs);
        //System.out.println("Time:"+time);

        Integer epochFlag = Integer.parseInt( util.lrtrim( line.substring(28,29) ));
        //System.out.println("epochFlag:"+epochFlag);
        // receiver offset

        epochNumSats = Integer.parseInt( util.lrtrim(line.substring(30,32)) );
        satellites = new String [epochNumSats];
        //System.out.println("Epoch numberofSats:"+epochNumSats);
        
        return line;
    }

    //
    // Read in the satellites which have an observation
    // for this epoch
    //
    public Integer getSats(String line) {
        Integer start = 32;
        Integer end   = 35;
        Integer len   = line.length();

        // if observations are13 or more then this will wrap onto the
        // next line
        for(int i=1 ; i <= epochNumSats ; i++) {
            if (end > len) { return 1;}
            String sat = line.substring(start,end);
            //System.out.println("Sat:"+sat);
            addSatellite(sat);

            start = start + 3;
            end = end + 3;
            if(i == 12 && epochNumSats > 12) {
                return 1;
            }
            if (end > len) { return 0;}
        }
        return 1;
    }

    // Read in the satellite data
    public Integer parseSatData(String line) {
        int length = line.length();
        int j = 0;
        String tmp;

        // get the first round of 
        //tmp = util.lrtrim( line.substring(0,13) );
        if(length <= 1) {return 1;}
        tmp = util.lrtrim( line.substring(0,14) );
        obs[j] = 0;
        if( tmp.length() > 0 ) {
            obs[j] = Double.parseDouble( tmp );
        }
        //System.out.println("OBS1:"+obs[j]);
        if(length <=14) { return 1; }

        tmp = util.lrtrim( line.substring(14,15) );
        ll[j] = 0;
        if( tmp.length() > 0 ) {
            ll[j] = Integer.parseInt( tmp );
        }
        //System.out.println("LL1:"+ll[j]);
        if(length <=15) { return 1; }

        tmp = util.lrtrim( line.substring(15,16) );
        ss[j] = 0;
        if( tmp.length() > 0 ) {
            ss[j] = Integer.parseInt( tmp );
        }
        //System.out.println("SS1:"+ss[j]);
        if(length <=18) {return 1;}

        j++;
        tmp = util.lrtrim( line.substring(18,30) );
        obs[j] = 0;
        if( tmp.length() > 0 ) {
            obs[j] = Double.parseDouble( tmp );
        }
        //System.out.println("OBS2:"+obs[j]);
        if(length <=31) { return 2;}
    
        tmp = util.lrtrim( line.substring(30,31) );
        ll[j] = 0;
        if( tmp.length() > 0 ) {
            ll[j] = Integer.parseInt( tmp );
        }
        //System.out.println("LL2:"+ll[j]);
        if(length <=32) { return 2;}

        tmp = util.ltrim( line.substring(31,32) );
        ss[j] = 0;
        if( tmp.length() > 0 ) {
            ss[j] = Integer.parseInt( tmp );
        }
        //System.out.println("SS2:"+ss[j]);
        if(length <=34) { return 2;}
        j++;

        tmp = util.lrtrim( line.substring(34,46) );
        obs[j] = 0;
        if( tmp.length() > 0 ) {
            obs[j] = Double.parseDouble( tmp );
        }
        //System.out.println("OBS3:"+obs[j]);
        if(length <=48) { return 3;}

        tmp = util.lrtrim( line.substring(47,48) );
        ll[j] = 0;
        if( tmp.length() > 0 ) {
            ll[j] = Integer.parseInt( tmp );
        }
        //System.out.println("LL3:"+ll[j]);
        if(length <=49) { return 3;}

        tmp = util.lrtrim( line.substring(48,49) );
        ss[j] = 0;
        if( tmp.length() > 0 ) {
            ss[j] = Integer.parseInt( tmp );
        }
        //System.out.println("SS3:"+ss[j]);
        if(length <=50) { return 3;}
        j++;

        tmp = util.lrtrim( line.substring(50,62) );
        obs[j] = 0;
        if( tmp.length() > 0 ) {
            obs[j] = Double.parseDouble( tmp );
        }
        //System.out.println("OBS4:"+obs[j]);
        if(length <=62) { return 4;}

        tmp = util.lrtrim( line.substring(62,63) );
        ll[j] = 0;
        if( tmp.length() > 0 ) {
            ll[j] = Integer.parseInt( tmp );
        }
        //System.out.println("LL4:"+ll[j]);
        if(length <=63) { return 4;}

        tmp = util.lrtrim( line.substring(63,64) );
        ss[j] = 0;
        if( tmp.length() > 0 ) {
            ss[j] = Integer.parseInt( tmp );
        }
        //System.out.println("SS4:"+ss[j]);
        if(length <=66) { return 4;}
        j++;

        tmp = util.lrtrim( line.substring(66,78) );
        obs[j] = 0;
        if( tmp.length() > 0 ) {
            obs[j] = Double.parseDouble( tmp );
        }
        //System.out.println("OBS5:"+obs[j]);
        if(length <=78) { return 5;}

        tmp = util.lrtrim( line.substring(78,79) );
        ll[j] = 0;
        if( tmp.length() > 0 ) {
            ll[j] = Integer.parseInt( tmp );
        }
        //System.out.println("LL5:"+ll[j]);
        if(length <=79) { return 5;}

        tmp = util.lrtrim( line.substring(79,80) );
        ss[j] = 0;
        if( tmp.length() > 0 ) {
            ss[j] = Integer.parseInt( tmp );
        }
        //System.out.println("SS5:"+ss[j]);
        if(length <=80) { return 5;}

        return 1;
    }

    public Integer getNumSats() {
        return epochNumSats; 
    }
    
    public long getTime() {
        //return timeInMilliSecs;
        return time;
    }
}
